package gateway.config;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.AbstractSwaggerUiConfigProperties.SwaggerUrl;
import org.springdoc.core.SwaggerUiConfigParameters;
import org.springdoc.core.SwaggerUiConfigProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.List;

import static org.springdoc.core.Constants.*;
import static org.springframework.util.CollectionUtils.isEmpty;

/**
 * https://editor.swagger.io
 * https://swagger.io/specification
 */
@Slf4j
@EnableScheduling
@RequiredArgsConstructor
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = SPRINGDOC_SWAGGER_UI_ENABLED, havingValue = "true", matchIfMissing = true)
class SwaggerConfig {
    final RouteDefinitionLocator locator;
    final SwaggerUiConfigParameters swaggerUiConfigParameters;
    final SwaggerUiConfigProperties swaggerUiConfigProperties;

    @Scheduled(fixedDelay = 180)
    public void refreshGroupedApi() { // 定时更新 API 分组
        // https://github.com/springdoc/springdoc-openapi-demos/blob/2.x/demo-microservices/gateway-service
        if (isEmpty(swaggerUiConfigProperties.getUrls())) swaggerUiConfigProperties.setUrls(swaggerUiConfigParameters.getUrls());
        List<RouteDefinition> routeDefinitions = locator.getRouteDefinitions().collectList().block();
        if (!isEmpty(routeDefinitions)) {
            routeDefinitions.forEach(routeDefinition -> {
                String name = routeDefinition.getUri().getHost();
                swaggerUiConfigProperties.getUrls().add(new SwaggerUrl(name, name + DEFAULT_API_DOCS_URL, routeDefinition.getId()));
            });
        }
    }

    @Bean
    @Profile("dev")
    ApplicationListener<ApplicationReadyEvent> swaggerUrlPrint() {
        return event -> { // https://blog.csdn.net/f641385712/article/details/88806639
            String port = event.getApplicationContext().getEnvironment().getProperty("local.server.port");
            log.info("{}：http://127.0.0.1:{}" + DEFAULT_WEB_JARS_PREFIX_URL.concat(SWAGGER_UI_URL), "Swagger UI", port);
            log.info("{}：http://127.0.0.1:{}" + DEFAULT_API_DOCS_URL, "API Docs", port);
        };
    }
}